package cc.eddic.practice.spring.webapi;

import cc.eddic.practice.spring.domain.Category;
import cc.eddic.practice.spring.domain.SubCategory;
import cc.eddic.practice.spring.dto.CategoryAddRequest;
import cc.eddic.practice.spring.dto.CategoryResponse;
import cc.eddic.practice.spring.dto.SubCategoryAddRequest;
import cc.eddic.practice.spring.dto.SubCategoryResponse;
import cc.eddic.practice.spring.repository.CategoryRepository;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/categories")
public class CategoryRestController {

    public CategoryRestController(CategoryRepository repository) {
        this.repository = repository;
    }


    @PostMapping
    public HttpEntity<?> add(@RequestBody final CategoryAddRequest model) {
//        log.debug("接收到model: {}", model);
        val category = repository.save(model.as());
//        log.debug("Category saved with ID: {}", category.getId());
        return ResponseEntity.created(ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}").buildAndExpand(category.getId()).toUri()).build();
    }


    @GetMapping("/{id}")
    public HttpEntity<CategoryResponse> get(@PathVariable("id") final long id) {
        if (log.isDebugEnabled()) log.debug("id = {}", id);
        val category = repository.findById(id).orElseThrow(NoSuchElementException::new);
        return ResponseEntity.ok(CategoryResponse.from(category));
    }

    @PostMapping("/{categoryId}/subcategories")
    public HttpEntity<?> add(@PathVariable("categoryId") Long categoryId, @RequestBody final SubCategoryAddRequest model){
        try {
            Category category = repository.findById(categoryId)
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Category not found"));

            SubCategory subCategory = model.as();
            category.add(subCategory);
            repository.save(category);

            URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                    .path("/{subCategoryId}")
                    .buildAndExpand(categoryId, subCategory.getId())
                    .toUri();

            return ResponseEntity.created(location).build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to add subcategory");
        }
    }



    @GetMapping("/{categoryId}/subcategories")
    public HttpEntity<?> get(@PathVariable("categoryId") Long categoryId){
        if (log.isDebugEnabled())log.debug("categoryId = {}",categoryId);
        val category = repository.findById(categoryId).orElseThrow(NoSuchElementException::new);
        if (log.isDebugEnabled())log.debug("run lazy load");
        return ResponseEntity.ok(category.getSubCategories().stream().map(SubCategoryResponse::from).collect(Collectors.toList()));
    }




    @GetMapping("/{categoryId}/subcategories/{subCategoryId}")
    public HttpEntity<?> get(@PathVariable("categoryId") Long categoryId, @PathVariable("subCategoryId") Long subCategoryId){
        if (log.isDebugEnabled())log.debug("categoryId = {}, subCategoryId = {}", categoryId, subCategoryId);
        Category category = repository.findById(categoryId).orElseThrow(NoSuchElementException::new);
        val subcategory = category.getSubCategories().stream()
                .filter(subCategory -> subCategory.getId()
                        .equals(subCategoryId)).findFirst()
                .orElseThrow(NoSuchElementException::new);

        return ResponseEntity.ok(SubCategoryResponse.from(subcategory));
    }






    private final CategoryRepository repository;





}
